﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Globalization;
using System.IO;
using System.Xml.Linq;

namespace GSync
{
    public class HashCodesCacheMngr: IHashCodesCacheManager
    {
        protected Dictionary<string, CacheRecord> cache;
        protected string cacheFilePath ;
        
        
        public HashCodesCacheMngr()
        {
            InitCacheFilePath();
            cache = new Dictionary<string, CacheRecord>();
            Load();
        }

        protected virtual void InitCacheFilePath()
        {
            if (string.IsNullOrEmpty(cacheFilePath))
            {
                cacheFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
                cacheFilePath = System.IO.Path.Combine(cacheFilePath, "gsync.cache");
            }
        }
        
        #region IHashCodesCacheManager Members

        public CacheRecord this[string ID]
        {
            get
            {
                if (string.IsNullOrEmpty(ID))
                    return null;


                if (cache.ContainsKey(ID))
                    return cache[ID];
                else
                    return null;
            }
            set
            {
                if (value == null)
                    throw new ArgumentNullException(); 

                if (cache.ContainsKey(ID))
                    cache[ID] = value;
                else
                    cache.Add(ID, value);
            }
        }


        public virtual void Load()
        {

            if (!System.IO.File.Exists(cacheFilePath))
                return;

            using (StreamReader reader = new StreamReader(cacheFilePath))
            {
                XDocument xDoc = XDocument.Load(reader);


                IFormatProvider culture = CultureInfo.CurrentCulture;

                cache = (from XElement cacheRec in xDoc.Root.Elements("cacheRecord")
                         select new CacheRecord()
                         {
                             ID = cacheRec.Attribute("id").Value,
                             Updated = DateTime.Parse(cacheRec.Attribute("updated").Value, culture),
                             HashCode = int.Parse(cacheRec.Attribute("hash").Value),
                             Type = cacheRec.Attribute("type").Value
                         }
                        ).ToDictionary(c => c.ID);

            }
        }

        public virtual void Save()
        {

            System.Xml.Linq.XDocument doc = new System.Xml.Linq.XDocument(
                new XElement( "cache", from cacheRec in cache.Values
                                       select new XElement("cacheRecord",  
                                                           new XAttribute("id",cacheRec.ID),
                                                           new XAttribute("type",cacheRec.Type),
                                                           new XAttribute("updated", cacheRec.Updated.ToString( CultureInfo.CurrentCulture)),
                                                           new XAttribute("hash",cacheRec.HashCode)) ));


        

            doc.Save(cacheFilePath);

        }

        #endregion

        #region IHashCodesCacheManager Members


        public virtual void Clear()
        {
            File.Delete(cacheFilePath);
            cache.Clear();
        }

        #endregion
    }

    public class CacheRecord
    {
        public static string Appointment = "appointment";
        public static string Contact = "contact";
        public string ID { get; set; }
        public DateTime Updated { get; set; }
        public int HashCode { get; set; }
        public string Type { get; set; }
    }

    
}
